import {
  defineComponent, PropType, toRefs, unref,
} from 'vue';
import {
  Input, Select, DatePicker, InputNumber, Col, Cascader, Switch, Radio,
} from 'ant-design-vue';
import { helpPlaceholder } from '@/common';
import KtImageUpload from '../KtImageUpload/KtImageUpload.vue';

const componentMap = new Map<KtForm.ComponentType, any>();
componentMap
  .set('Input', Input)
  .set('InputNumber', InputNumber)
  .set('InputTextArea', Input.TextArea)
  .set('Select', Select)
  .set('DatePicker', DatePicker)
  .set('RangePicker', DatePicker.RangePicker)
  .set('Cascader', Cascader)
  .set('Switch', Switch)
  .set('Radio', Radio)
  .set('RadioGroup', Radio.Group)
  .set('ImageUpload', KtImageUpload);

const FormItem = defineComponent({
  inheritAttrs: false,
  props: {
    form: {
      type: Object as PropType<Record<string, any>>,
      required: true,
    },
    schema: {
      type: Object as PropType<KtForm.IFormSchema>,
      required: true,
    },
    disabled: {
      required: true,
      type: Boolean,
    },
  },
  setup(props) {
    const { schema, disabled, form } = toRefs(props);

    function handleRules() {
      const { required, rules } = schema.value;
      const fieldRule: any = [];
      if (rules) {
        rules instanceof Object && (fieldRule.push(rules));
        rules instanceof Array && (fieldRule.push(...rules));
      }
      if (required !== false) {
        const rule = {
          required: true,
          message: helpPlaceholder(unref(schema), true),
        };
        if (schema.value.component === 'RangePicker') {
          (rule as any).type = 'array';
        }
        if (schema.value.component === 'InputNumber') {
          (rule as any).type = 'number';
        }
        fieldRule.unshift(rule);
      }
      return fieldRule;
    }

    function getItemProps() {
      return {
        filed: schema.value.field,
        labelCol: schema.value.labelCol,
        labelAlign: schema.value.labelAlign,
        wrapperCol: schema.value.wrapperCol,
        colon: schema.value.colon || true,
        autoLink: schema.value.autoLink || true,
      };
    }

    function getComponent() {
      const tempSchema = unref(schema);
      const eventKey = 'onChange';
      // 默认change事件
      const on = {
        [eventKey]: (e: any) => {
          // 组件输入的值
          const value = (e && e.target) ? e.target.value : e;
          if (tempSchema.componentProps && tempSchema.componentProps[eventKey]) {
            tempSchema.componentProps[eventKey](value);
          }
          // 组件输入的值
          form.value[tempSchema.field] = typeof value === 'string' ? value.trim() : value;
        },
      };
      const Component = componentMap.get(tempSchema.component);

      const isDisabled = disabled.value ?? tempSchema.componentProps?.disabled;

      const placeholder = tempSchema.componentProps?.placeholder ?? helpPlaceholder(tempSchema);

      if (['Cascader'].includes(tempSchema.component)) {
        return (
            <Component
                placeholder={placeholder}
                disabled={isDisabled}
                { ...on }
                {...unref(tempSchema.componentProps) }
            />
        );
      }
      return (
            <Component
                placeholder={placeholder}
                disabled={isDisabled}
                value={props.form[tempSchema.field]}
                { ...on }
                {...unref(tempSchema.componentProps) }
            />
      );

    }

    function renderItem() {
      const { label, field, itemCol } = schema.value;

      return (
          <a-form-Item
              label={label}
              prop={field}
              rules={handleRules()}
              {...{ props: getItemProps() } }
              style={{ width: itemCol ? '100%' : 'auto' }}
          >
            {
              getComponent()
            }
          </a-form-Item>
      );
    }

    return () => {
      const { component, itemCol } = props.schema;
      if (!componentMap.has(component)) return null;

      if (itemCol) {
        // @ts-ignore
        return <Col {...{ props: itemCol }}>
          {renderItem()}
        </Col>;
      }
      return renderItem();

    };
  },
});

export default FormItem;
